//@author A0078695H
/*

	Unit tests for cmd class

*/

#include "../command.h"
#include "../CmdAdd.h"
#include "../CmdDisplay.h"
#include "../CmdClear.h"
#include "../CmdDel.h"
#include "../CmdSort.h"
#include "../CmdSearch.h"
#include "../CmdExit.h"
#include "../CmdInvalid.h"
#include "../CmdUpdate.h"
#include "../CmdDone.h"
#include "../CmdUndo.h"
#include "../Task.h"

TEST(cmdTest, testCmdAdd) {
	CmdAdd c = CmdAdd(cmdTypes::ADD, vector<string>(1, "abc"), "abc");
	EXPECT_EQ(c.getCmdType(), cmdTypes::ADD);
	EXPECT_EQ(c.toString(), "abc");
	Task t = c.getTask();
	EXPECT_TRUE(t.isValid());
	EXPECT_EQ(t.getTaskName(), "abc");
}

TEST(cmdTest, testCmdDisplay) {
	CmdDisplay c = CmdDisplay(cmdTypes::DISPLAY, vector<string>(1, "abc"), "abc");
	EXPECT_EQ(c.getCmdType(), cmdTypes::DISPLAY);
	EXPECT_EQ(c.toString(), "abc");
}

TEST(cmdTest, testCmdDel) {
	int indices[] = {1, 2, 3};
	CmdDel c = CmdDel(cmdTypes::DEL, vector<string>(1, "abc"), "abc", vector<int>(indices, indices+3));
	EXPECT_EQ(c.getCmdType(), cmdTypes::DEL);
	EXPECT_EQ(c.toString(), "abc");
	EXPECT_EQ(c.getIds().size(), 3);
	EXPECT_EQ(c.getIds()[0], 1);
	EXPECT_EQ(c.getIds()[1], 2);
	EXPECT_EQ(c.getIds()[2], 3);
	int indices2[4] = {4, 5, 6, 7};
	c.setIds(vector<int>(indices2, indices2+4));
	EXPECT_EQ(c.getIds().size(), 4);
	EXPECT_EQ(c.getIds()[0], 4);
	EXPECT_EQ(c.getIds()[1], 5);
	EXPECT_EQ(c.getIds()[2], 6);
	EXPECT_EQ(c.getIds()[3], 7);
}

TEST(cmdTest, testCmdUpdate) {
	CmdUpdate c = CmdUpdate(cmdTypes::UPDATE, vector<string>(1, "1"), "abc", 1);
	EXPECT_EQ(c.getCmdType(), cmdTypes::UPDATE);
	EXPECT_EQ(c.toString(), "abc");
	EXPECT_EQ(c.getId(), 1);
	c.setId(2);
	EXPECT_EQ(c.getId(), 2);
	EXPECT_EQ(c.getUdtType(), UdtType::SELECT);
	EXPECT_EQ(c.getModifiedTask().isValid(), false);
	string arr[] = {"2", "my task"};
	c = CmdUpdate(cmdTypes::UPDATE, vector<string>(arr, arr+2), "abc", 2);
	EXPECT_EQ(c.getId(), 2);
	EXPECT_EQ(c.getUdtType(), UdtType::EDIT);
	EXPECT_EQ(c.getModifiedTask().isValid(), true);
	Task t = Parser::stringToTask("my task");
	c = CmdUpdate(cmdTypes::UPDATE, vector<string>(arr, arr+2), "abc", 2, t);
	EXPECT_EQ(c.getModifiedTask().isValid(), true);
	//EXPECT_EQ(c.getModifiedTask(), t);

}

TEST(cmdTest, testCmdDone) {
	int indices[] = {1, 2, 3};
	CmdDone c = CmdDone(cmdTypes::DONE, vector<string>(1, "abc"), "abc", vector<int>(indices, indices+3));
	EXPECT_EQ(c.getCmdType(), cmdTypes::DONE);
	EXPECT_EQ(c.getDoneType(), CmdDone::DoneType::MARK_DONE);
	EXPECT_EQ(c.getIds().size(), 3);
	EXPECT_EQ(c.getIds()[0], 1);
	EXPECT_EQ(c.getIds()[1], 2);
	EXPECT_EQ(c.getIds()[2], 3);
	EXPECT_EQ(c.toString(), "abc");

	c = CmdDone(cmdTypes::UNDONE, vector<string>(1, "abc"), "abc", vector<int>(indices, indices+3));
	EXPECT_EQ(c.getDoneType(), CmdDone::DoneType::MARK_UNDONE);
	int indices2[4] = {4, 5, 6, 7};
	c.setIds(vector<int>(indices2, indices2+4));
	EXPECT_EQ(c.getIds().size(), 4);
	EXPECT_EQ(c.getIds()[0], 4);
	EXPECT_EQ(c.getIds()[1], 5);
	EXPECT_EQ(c.getIds()[2], 6);
	EXPECT_EQ(c.getIds()[3], 7);
}

TEST(cmdTest, testCmdFilter) {
	string arr[] = {"today", "friday"};
	CmdFilter c = CmdFilter(cmdTypes::FILTER, vector<string>(arr, arr+2), "abc");
	EXPECT_EQ(c.getKeywordVector().size(), 2);
	c = CmdFilter(cmdTypes::FILTER, vector<string>(1, "abc"), "abc");
	EXPECT_EQ(c.getKeywordVector().size(), 1);
	EXPECT_EQ(c.getKeywordVector()[0], "abc");
}

TEST(cmdTest, testCmdHelp) {
	CmdHelp c = CmdHelp(cmdTypes::HELP, vector<string>(1, "add"), "add ?", cmdTypes::ADD);
	EXPECT_EQ(CmdHelp::loadHelpInfo("NON_EXISTING_FILE"), 1);
	for (int i=cmdTypes::ADD; i!=cmdTypes::HELP; i++) {
		for (int j=0; j<CmdHelp::COMMAND_HELP_STR_ARR.size(); j++) {
			EXPECT_EQ(CmdHelp::toHelpInfoString(static_cast<cmdTypes>(i)), "");
			EXPECT_EQ(CmdHelp::toHelpInfoString(static_cast<cmdTypes>(i)), "");
		}
	}
	EXPECT_EQ(c.getHelpType(), cmdTypes::ADD);
}

TEST(cmdTest, testCmdInvalid) {
	CmdInvalid c = CmdInvalid(cmdTypes::INVALID, vector<string>(1, "abc"), "abc", ErrorType::ERROR_ARG_INVALID);
	EXPECT_EQ(c.getErrorType(), ErrorType::ERROR_ARG_INVALID);
	EXPECT_EQ(CmdInvalid::ERROR_MSG[c.getErrorType()], "The command string's arguments are not valid");

	c = CmdInvalid(cmdTypes::INVALID, vector<string>(1, "abc"), "abc", ErrorType::ERROR_IDX_INVALID);
	EXPECT_EQ(c.getErrorType(), ErrorType::ERROR_IDX_INVALID);
	EXPECT_EQ(CmdInvalid::ERROR_MSG[c.getErrorType()], "The command index is not valid");

	c = CmdInvalid(cmdTypes::INVALID, vector<string>(1, "abc"), "abc", ErrorType::ERROR_TOO_FEW_ARG);
	EXPECT_EQ(c.getErrorType(), ErrorType::ERROR_TOO_FEW_ARG);
	EXPECT_EQ(CmdInvalid::ERROR_MSG[c.getErrorType()], "The command string has too few arguments");

	c = CmdInvalid(cmdTypes::INVALID, vector<string>(1, "abc"), "abc", ErrorType::ERROR_UNRECOG_CMD);
	EXPECT_EQ(c.getErrorType(), ErrorType::ERROR_UNRECOG_CMD);
	EXPECT_EQ(CmdInvalid::ERROR_MSG[c.getErrorType()], "The command is unrecognized by Taak");
}

TEST(cmdTest, testCmdSearch) {
	string arr[] = {"today", "friday"};
	CmdSearch c = CmdSearch(cmdTypes::SEARCH, vector<string>(arr, arr+2), "abc");
	EXPECT_EQ(c.getKeywordVector().size(), 2);
	EXPECT_EQ(c.getKeywordVector()[0], "today");
	EXPECT_EQ(c.getKeywordVector()[1], "friday");
	c = CmdSearch(cmdTypes::SEARCH, vector<string>(1, "abc"), "abc");
	EXPECT_EQ(c.getKeywordVector().size(), 1);
	EXPECT_EQ(c.getKeywordVector()[0], "abc");
}

TEST(cmdTest, testCmdSort) {
	string arr[] = {"date", "end"};
	CmdSort c = CmdSort(cmdTypes::SORT, vector<string>(arr, arr+2), "abc");
	EXPECT_EQ(c.getKeywordVector().size(), 2);
	EXPECT_EQ(c.getKeywordVector()[0], "date");
	EXPECT_EQ(c.getKeywordVector()[1], "end");
}

TEST(cmdTest, testCmd) {
	Cmd c = Cmd(cmdTypes::ADD, vector<string>(), "abc");
	EXPECT_EQ(c.getParams().size(), 0);
	vector<string> p(1, "my para");
	c.setParams(p);
	EXPECT_EQ(c.getParams().size(), 1);
	EXPECT_EQ(c.getParams()[0], "my para");

	c.setCmdType(cmdTypes::UPDATE);
	EXPECT_EQ(c.getCmdType(), cmdTypes::UPDATE);
}